package com.weaver.qfengx.api.edoc;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.weaver.qfengx.NumberUtils;
import com.weaver.qfengx.RequestUtils;
import com.weaver.qfengx.StringUtils;
import com.weaver.qfengx.api.edoc.config.EdocConfig;
import com.weaver.qfengx.api.edoc.entity.FileModel;
import com.weaver.qfengx.api.edoc.entity.MemberPermission;
import com.weaver.qfengx.config.DevModeConfig;
import com.weaver.qfengx.entity.Result;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import org.apache.commons.compress.utils.Lists;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 鸿翼网盘相关接口对接封装
 */
public class EdocApiService {

    private String host = "";
    private OkHttpClient client;

    public EdocApiService(OkHttpClient client, String host) {
        this.client = client;
        this.host = host;
    }

    public EdocApiService(String host) {
        this.client = new OkHttpClient();
        this.host = host;
    }
    public EdocApiService(String host, String logTable) {
        this.client =  new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(NumberUtils.parseInt(DevModeConfig.getPropConfig("edoc.api.readtimeout", "300").getValue()), TimeUnit.SECONDS)
                .writeTimeout(NumberUtils.parseInt(DevModeConfig.getPropConfig("edoc.api.writetimeout", "300").getValue()), TimeUnit.SECONDS)
                .addInterceptor(new ReqLogInterceptor(logTable))
                .build();
        this.host = host;
    }

    private Result createResult(Response response) throws IOException {
        if (response.isSuccessful()) {
            String respBody = response.body().string();
            System.out.println(respBody);
            JSONObject jsonObject = JSONObject.parseObject(respBody);
            if (StringUtils.equals("4", jsonObject.getString("errorCode"))) {
                return Result.fail("token失效");
            }
            if (jsonObject.getInteger("result") == 0) {
                return Result.ok(jsonObject.get("data"));
            } else {
                return Result.fail("请求出错").setData(respBody);
            }
        } else {
            return Result.fail("请求异常");
        }
    }

    /**
     * 获取token 认证接口
     *
     * @return
     */
    public Result getToken(String loginName, String ip, String integrationKey) throws IOException {
        Map<String, Object> reqParam = Maps.newHashMap();
        reqParam.put("LoginName", loginName);
        reqParam.put("IPAddress", ip);
        reqParam.put("IntegrationKey", integrationKey);
        Response response = RequestUtils.doPostByJson(this.client, this.host + EdocConfig.getToken, reqParam);
        return createResult(response);
    }

    public Result getToken(String loginName, String integrationKey) throws IOException {
        return getToken(loginName, "127.0.0.1", integrationKey);
    }

    /**
     * 判断指定文件下是否存在指定文件夹名
     *
     * @param token
     * @param folderName
     * @param folderId
     * @return
     */
    public Result checkFolderIsExist(String token, String folderName, String folderId) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("folderName", folderName);
        reqParams.put("folderId", folderId);
        reqParams.put("token", token);
        Response response = RequestUtils.doGetWithoutChange(this.client, this.host + EdocConfig.checkFolderIsExist, reqParams);
        return createResult(response);
    }

    public Result createFolder(String token, String parentFolderId, String name) throws IOException {
        Map<String, Object> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("ParentFolderId", parentFolderId);
        reqParams.put("Name", name);
        Response response = RequestUtils.doPostByJson(this.client, this.host + EdocConfig.createFolder, reqParams);
        return createResult(response);
    }

    /**
     * 发送上传请求，获取code
     *
     * @return
     */
    public Result getUploadCode(String token, String folderId, String fileName,
                                long size, String type,
                                String attachType, FileModel fileModel) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("folderId", folderId);
        reqParams.put("fileName", fileName);
        reqParams.put("size", StringUtils.val(size));
        reqParams.put("type", type);
        reqParams.put("attachType", attachType);
        reqParams.put("fileModel", StringUtils.val(fileModel));

        Response response = RequestUtils.doPost(this.client, this.host + EdocConfig.getUploadCode, reqParams);
        return createResult(response);
    }

    /**
     * 上传文件
     */
    public Result uploadFile(String token, String uploadId, String regionHash, int regionId,
                             String fileName, long size, int chunks, long chunkSize, long blockSize,
                             InputStream inputStream) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("uploadId", uploadId);
        reqParams.put("regionHash", regionHash);
        reqParams.put("regionId", StringUtils.val(regionId));
        reqParams.put("fileName", fileName);
        reqParams.put("size", StringUtils.val(size));
        reqParams.put("chunks", StringUtils.val(chunks));
        reqParams.put("chunkSize", StringUtils.val(chunkSize));
        reqParams.put("blockSize", StringUtils.val(blockSize));
        // 这里地址需要凭借code 和 token
        Response response = RequestUtils.uploadFileAndParam(this.client, this.host + EdocConfig.uploadFile + "?token=" + token, inputStream, "file", fileName, reqParams);
        if (response.isSuccessful()) {
            String body = response.body().string();
            JSONObject bodyObj = JSONObject.parseObject(body);
            if (bodyObj.getInteger("errorCode") == 0) {
                return Result.ok(bodyObj);
            } else {
                return Result.fail("上传失败").setData(bodyObj);
            }
        } else {
            return Result.fail("上传异常");
        }
    }

    /**
     * 批量设置文件权限
     */
    public Result setPermission(String token, int fileId, List<MemberPermission> memberPermissions) throws IOException {
        Map<String, Object> reqParams = Maps.newHashMap();
        reqParams.put("FileId", fileId);
        reqParams.put("Token", token);
        List<Map<String, Object>> permissionList = Lists.newArrayList();
        for (MemberPermission memberPermission : memberPermissions) {
            Map<String, Object> permissions = Maps.newHashMap();
            permissions.put("MemberId", memberPermission.getMemberId());
            permissions.put("MemberType", memberPermission.getMemberType());
            permissions.put("PermType", memberPermission.getMemberType());
            permissions.put("PermCateId", memberPermission.getPermCateId());
            if (Objects.nonNull(memberPermission.getStartTime())) {
                permissions.put("StartTime", memberPermission.getStartTime());
            }
            if (Objects.nonNull(memberPermission.getExpiredTime())) {
                permissions.put("ExpiredTime", memberPermission.getExpiredTime());
            }
            permissionList.add(permissions);
        }
        reqParams.put("Permissions", permissionList);
        Response response = RequestUtils.doPostByJson(this.client, this.host + EdocConfig.setPermission, reqParams);
        return createResult(response);
    }

    public Result getFilePermCates(String token, String lang, boolean returnPermValues) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("lang", lang);
        reqParams.put("returnPermValues", StringUtils.val(returnPermValues));
        return createResult(RequestUtils.doGetWithoutChange(this.client, this.host + EdocConfig.getFilePermCates, reqParams));
    }

    public Result getFolderIdInFolderByfolderName(String token, String folderName, String folderId) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("folderName", folderName);
        reqParams.put("folderId", folderId);
        return createResult(RequestUtils.doGetWithoutChange(this.client, this.host + EdocConfig.getFolderIdInFolderByfolderName, reqParams));
    }

    /**
     * 重命名文件夹
     * @param token
     * @param newname
     * @param docid
     * @return
     */
    public Result renameFolder(String token, String newname, String docid) throws IOException {
        Map<String, Object> reqParam = Maps.newHashMap();
        reqParam.put("Token", token);
        reqParam.put("NewName", newname);
        reqParam.put("DocId", docid);
        Response response = RequestUtils.doPostByJson(this.client, this.host + EdocConfig.renameFolder, reqParam);
        return createResult(response);
    }

    /**
     * 根据账号获取用户信息
     */
    public Result getUserInfoByAccount(String token, String account) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("account", account);
        return createResult(RequestUtils.doGetWithoutChange(this.client, this.host + EdocConfig.getUserInfoByAccount, reqParams));
    }

    /**
     * 删除文件
     */
    public Result deleteFile(String token, String fileIds) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("fileIds", fileIds);
        return  createResult(RequestUtils.doGetWithoutChange(this.client, this.host + EdocConfig.deleteFile, reqParams));
    }

    /**
     * 获取文件和文件夹列表
     */
    public Result getFileAndFolder(String token, String folderId) throws IOException{
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("folderId", folderId);
        return createResult(RequestUtils.doGetWithoutChange(this.client, this.host + EdocConfig.getFileAndFolder, reqParams));
    }

    /**
     * 根据文件名路径获取文件信息
     */
    public Result getFileByNamePath(String token, String fileNamePath) throws IOException {
        Map<String, String> reqParams = Maps.newHashMap();
        reqParams.put("token", token);
        reqParams.put("fileNamePath", fileNamePath);
        return createResult(RequestUtils.doGetWithoutChange(this.client, this.host + EdocConfig.getFileIdByNamePath, reqParams));
    }

    /**
     * 删除文件和文件夹列表
     */
    public Result removeFolderAndFile(String token, List<Integer> fileIdList, List<Integer> folderIdList) throws IOException {
        Map<String, Object> reqParams = Maps.newHashMap();
        reqParams.put("Token", token);
        reqParams.put("FileIdList", fileIdList);
        reqParams.put("FolderIdList", folderIdList);
        Response response = RequestUtils.doPostByJson(this.client, this.host + EdocConfig.removeFolderListAndFileList, reqParams);
        return createResult(response);
    }

}
